# !/usr/bin/env python
# -*-coding:utf-8 -*-

"""
# File       : base_info_view.py
# Time       ：2023/11/2 14:57
# Author     ：YangYong
# version    ：python 3.10
# Description：基本信息
"""
import ctypes
import os
import platform
from datetime import datetime

from flask_restx import Resource, fields

from apis.notice.model.alarm import Alarm
from apis.data_screen import data_screen_ns
from apis.orderlines.models import Process, ProcessInstance
from orderlines.utils.orderlines_enum import ProcessStates
from public.api_utils.api_decorator import handle_api_error
from public.base_model import db
from public.base_response import generate_response, MarshalModel

base_info = {
    'process_total': fields.String(description='流程数量'),
    'process_success_total': fields.String(description='流程成功数量'),
    'process_failure_total': fields.String(description='流程失败数量'),
    'process_run_total': fields.String(description='流程运行总数'),
    'alarm_count': fields.String(description='告警总数'),
    'free_space_mb': fields.String(description='可用空间'),
    'safe_run_day': fields.String(description='运行天数'),
}

base_info_marshal = MarshalModel('base_info', data_screen_ns)


class BaseInfoView(Resource):
    url = '/base_info'

    def __init__(self, *args, **kwargs):
        super(BaseInfoView, self).__init__(*args, **kwargs)
        self.current_data = datetime.now()

    @staticmethod
    def get_free_space_mb():
        if platform.system() == 'Windows':
            folder = 'C:\\'
            free_bytes = ctypes.c_ulonglong(0)
            ctypes.windll.kernel32.GetDiskFreeSpaceExW(ctypes.c_wchar_p(folder), None, None, ctypes.pointer(free_bytes))
            return f"{round(free_bytes.value / 1024 / 1024 / 1024)}GB"
        else:
            folder = '/'
            st = os.statvfs(folder)
            return f"{round(st.f_bavail * st.f_frsize / 1024 / 1024 / 1024)}GB"

    @handle_api_error()
    @data_screen_ns.doc(description='系统基本信息')
    @data_screen_ns.marshal_with(base_info_marshal.detail_response(base_info, False))
    def get(self):
        """获取系统基本信息"""
        process_total = db.session.query(Process.id).filter(Process.active == 1).all()
        process_success_total = db.session.query(ProcessInstance.id).filter(
            ProcessInstance.active == 1, ProcessInstance.process_status == ProcessStates.green.value).all()
        process_failure_total = db.session.query(ProcessInstance.id).filter(
            ProcessInstance.active == 1, ProcessInstance.process_status == ProcessStates.green.value).all()
        process_run_total = db.session.query(ProcessInstance.id).filter(ProcessInstance.active == 1).all()
        alarm_count = db.session.query(Alarm).filter(Alarm.active == 1).all()
        free_space_mb = self.get_free_space_mb()
        obj = db.session.query(ProcessInstance).filter(
            ProcessInstance.active == 1).order_by(ProcessInstance.id).first()
        if not obj:
            safe_run_day = 0
        else:
            safe_run_day = (self.current_data - obj.start_time).days

        response_data = {
            'process_total': len(process_total),
            'process_success_total': len(process_success_total),
            'process_failure_total': len(process_failure_total),
            'process_run_total': len(process_run_total),
            'alarm_count': len(alarm_count),
            'free_space_mb': free_space_mb,
            'safe_run_day': safe_run_day
        }
        return generate_response(response_data)
